/**
 * 
 */
package wpmp.security.mgr.web;

import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import wcommons.lang.NumberUtils;
import wpmp.extjs3.ExtjsUtils;
import wpmp.extjs3.data.Form;
import wpmp.extjs3.data.TreeNode;
import wpmp.security.mgr.Statics;
import wpmp.security.mgr.base.BaseAction;
import wpmp.security.mgr.base.DefaultBaseAction;
import wpmp.security.mgr.entity.Operation;
import wpmp.security.mgr.entity.Resource;
import wpmp.security.mgr.service.OperationService;
import wpmp.security.mgr.service.ResourceService;

/**
 * @author Wayne.Wang<5waynewang@gmail.com>
 * @since 2:33:14 PM Mar 18, 2013
 */
@Action("resource")
@Results({ @Result(name = BaseAction.LIST, location = "/WEB-INF/resource/list.jsp"),
		@Result(name = BaseAction.INPUT, location = "/WEB-INF/resource/input.jsp"),
		@Result(name = ResourceAction.SELECT, location = "/WEB-INF/resource/select.jsp") })
public class ResourceAction extends DefaultBaseAction<Resource> {

	private static final long serialVersionUID = 1L;

	private static final Logger LOG = LoggerFactory.getLogger(ResourceAction.class);

	private static final String OPERATION_CHECKBOX_HTML = "{boxLabel: '%s',name:'operationIds',inputValue: %s,checked: %s}";

	private static final String OPERATION_HTML = ",{xtype:'checkboxgroup',fieldLabel:'操作类型',columns:5,anchor:'100%',items:[${}]}";

	static final String SELECT = "select";

	@Autowired
	private ResourceService service;
	@Autowired
	private OperationService operationService;

	public String select() throws Exception {
		return SELECT;
	}

	@Override
	public String input() throws Exception {
		final HttpServletRequest req = this.getRequest();

		String parentName = null;
		Resource parent = null;
		if (NumberUtils.gtZero(entity.getParentId())) {
			parent = service.get(entity.getParentId());
		}
		else if (NumberUtils.gtZero(entity.getId())) {
			parent = service.getParent(entity.getId());
		}
		if (parent != null) {
			parentName = parent.getName();
		}
		req.setAttribute("PARENT_NAME", StringUtils.trimToEmpty(parentName));

		boolean isLeafReadOnly = false;
		if (NumberUtils.gtZero(entity.getId())) {
			int maxOrderNum = service.getMaxChildOrderNum(entity.getId());
			isLeafReadOnly = maxOrderNum > 0;
		}
		req.setAttribute("IS_LEAF_READ_ONLY", isLeafReadOnly);

		// 设置操作类型选项
		final List<Operation> operations = operationService.list();
		if (CollectionUtils.isEmpty(operations)) {
			req.setAttribute("operationIdsHTML", StringUtils.EMPTY);
		}
		else {
			final List<Operation> checkedOperations = operationService.getResourceOperations(entity.getId());

			final StringBuilder operationIdsHTML = new StringBuilder();
			for (Operation operation : operations) {
				operationIdsHTML.append(",");

				boolean checked = false;
				if (CollectionUtils.isNotEmpty(checkedOperations)) {
					for (Operation checkedOperation : checkedOperations) {
						if (NumberUtils.eq(checkedOperation.getId(), operation.getId())) {
							checked = true;
							break;
						}
					}
				}

				operationIdsHTML.append(String.format(OPERATION_CHECKBOX_HTML, operation.getName(), operation.getId(),
						checked));
			}

			req.setAttribute("operationIdsHTML",
					StringUtils.replace(OPERATION_HTML, "${}", operationIdsHTML.deleteCharAt(0).toString()));
		}
		return INPUT;
	}

	@Override
	public String list() throws Exception {
		// 根节点名称
		this.getRequest().setAttribute("ROOT_NAME", service.get(Statics.ROOT_ID).getName());
		return LIST;
	}

	public void listJSON() throws Exception {
		final HttpServletRequest req = this.getRequest();

		Long id = entity.getId();
		if (!NumberUtils.gtZero(id)) {
			String node = req.getParameter("node");
			if (StringUtils.isNotBlank(node)) {
				id = Long.valueOf(node);
			}
		}
		if (!NumberUtils.gtZero(id)) {
			id = Statics.ROOT_ID;// root 节点
		}

		final List<TreeNode> treeNodes = new LinkedList<TreeNode>();
		final List<Resource> children = service.getChildren(id);
		for (Resource child : children) {
			final TreeNode treeNode = new TreeNode();
			treeNode.setId(child.getId().toString());
			treeNode.setLeaf(child.getIsLeaf());
			treeNode.setText(child.getName());
			treeNode.addAttribute("orderNum", child.getOrderNum());
			treeNodes.add(treeNode);
		}
		this.renderJson(TreeNode.toJSONString(treeNodes));
	}

	public void getJSON() throws Exception {
		final Resource result = service.get(entity.getId());

		if (LOG.isDebugEnabled()) {
			LOG.debug("{}", result);
		}

		if (result == null) {
			LOG.warn("can not found Resource by id[{}]", entity.getId());

			this.renderJson(ExtjsUtils.getDefaultErrorFormJSONString(Statics.DEFAULT_ERROR_MSG));
			return;
		}

		final String jsonString = Form.newInstance(result).toJSONString();

		if (LOG.isDebugEnabled()) {
			LOG.debug(jsonString);
		}

		this.renderJson(jsonString);
	}

	public void insertJSON() throws Exception {
		this.renderJson(service.insert(entity).toJSONString());
	}

	public void updateJSON() throws Exception {
		this.renderJson(service.update(entity).toJSONString());
	}

	public void deleteJSON() throws Exception {
		this.renderJson(service.delete(entity.getId()).toJSONString());
	}

	public void sortJSON() throws Exception {
		this.renderJson(service.sort(entity).toJSONString());
	}

	@Override
	public Resource getModel0() {
		if (entity == null) {
			entity = new Resource();
		}
		return entity;
	}

}
